package api

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"supershare/backend/middleware"
	"supershare/backend/models"

	// 添加HTTP客户端相关包
	// "bytes"
	// "encoding/json"
	// "io/ioutil"
	// "net/http"
	// "time"

	"time"

	"github.com/beego/beego/v2/core/logs"
	"github.com/beego/beego/v2/server/web"
)

// DeviceController 设备控制器
type DeviceController struct {
	web.Controller
}

// OpenDoor 开门接口
func (c *DeviceController) OpenDoor() {
	// 获取当前会员信息
	member, err := middleware.GetCurrentMember(c.Ctx)
	if err != nil || member == nil {
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "未授权访问",
		}
		c.ServeJSON()
		return
	}

	// 获取门店ID参数
	storeIdStr := c.GetString("store_id")
	if storeIdStr == "" {
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "门店ID不能为空",
		}
		c.ServeJSON()
		return
	}

	// 转换门店ID为整数
	storeId, err := strconv.ParseInt(storeIdStr, 10, 64)
	if err != nil {
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "无效的门店ID",
		}
		c.ServeJSON()
		return
	}

	// 检查门店是否存在
	store, err := models.GetStoreById(storeId)
	if err != nil || store == nil {
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "门店不存在",
		}
		c.ServeJSON()
		return
	}

	// 加盟商权限验证 - 确保会员只能访问自己加盟商的门店
	if member.FranchiseId > 0 && store.FranchiseId != member.FranchiseId {
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "您无权操作该门店的设备",
		}
		c.ServeJSON()
		return
	}

	// 检查用户是否有有效预订
	hasActiveBooking, err := models.CheckUserHasActiveBooking(int(member.Id), int(storeId))
	if err != nil {
		logs.Error("检查用户预订状态失败: %v", err)
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "系统错误，请稍后再试",
		}
		c.ServeJSON()
		return
	}

	if !hasActiveBooking {
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "您没有该门店的有效预订，不能操作",
		}
		c.ServeJSON()
		return
	}
	venue_id, _ := c.GetInt64("venue_id", 0)

	// 查找门禁设备
	var doorDevice *models.Device
	if venue_id == 0 {
		// 获取门店的设备列表
		devices, err := models.GetDeviceByStoreId(storeId)
		if err != nil {
			logs.Error("获取门店设备失败: %v", err)
			c.Data["json"] = map[string]interface{}{
				"success": false,
				"message": "系统错误，无法获取门禁设备信息",
			}
			c.ServeJSON()
			return
		}

		for _, device := range devices {
			if device.DeviceType == 0 { // 门禁设备类型为1
				doorDevice = device
				break
			}
		}
	} else {
		// 按venue_id查找设备
		devices, err := models.GetDeviceByVenueId(venue_id)
		if err != nil {
			logs.Error("获取门店设备失败: %v", err)
			c.Data["json"] = map[string]interface{}{
				"success": false,
				"message": "系统错误，无法获取门禁设备信息",
			}
			c.ServeJSON()
			return
		}

		for _, device := range devices {
			if device.DeviceType == 1 { // 门禁设备类型为1
				doorDevice = device
				break
			}
		}
	}

	if doorDevice == nil {
		logs.Error("门店未配置门禁设备, storeId: %d", storeId)
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "该门店未配置门禁设备，请联系管理员",
		}
		c.ServeJSON()
		return
	}

	// 检查设备状态
	if doorDevice.Status != 1 {
		statusMsg := "未知"
		switch doorDevice.Status {
		case 0:
			statusMsg = "离线"
		case 2:
			statusMsg = "故障"
		}

		logs.Error("门禁设备状态异常, deviceId: %d, status: %d", doorDevice.Id, doorDevice.Status)
		c.Data["json"] = map[string]interface{}{
			"success": false,
			"message": "门禁设备当前" + statusMsg + "，无法操作",
		}
		c.ServeJSON()
		return
	}
	cmdType, _ := c.GetInt8("type", 0)
	switch cmdType {
	case 0: //开门
		delay := 10
		cmd := fmt.Sprintf(`{"deviceId":"%s","command":"1004","params":"{\"Cmd\":\"RemoteOpenDoor\",\"ID\":1,\"Lock\":190,\"Type\":0,\"Delay\":%d}"}`, doorDevice.DeviceNo, delay)
		success, errorMsg := sendCommand(doorDevice, cmd)
		if !success {
			logs.Error("发送开门指令失败: %s", errorMsg)
			c.Data["json"] = map[string]interface{}{
				"success": false,
				"message": "操作失败: " + errorMsg,
			}
			c.ServeJSON()
			return
		}

		// 记录开门日志
		logEntry := &models.OperationLog{
			UserId:        member.Id,
			Username:      member.Phone,
			Method:        c.Ctx.Request.Method,
			Path:          c.Ctx.Request.URL.Path,
			Ip:            c.Ctx.Input.IP(),
			OperationType: "device:open",
			Description:   "用户开门操作，门店ID: " + storeIdStr + ", 设备ID: " + strconv.FormatInt(doorDevice.Id, 10),
		}
		err = models.AddOperationLog(logEntry)
		if err != nil {
			logs.Error("记录开门日志失败: %v", err)
		}

		// 返回成功结果
		c.Data["json"] = map[string]interface{}{
			"success": true,
			"message": "开门成功",
			"data": map[string]interface{}{
				"device_name":    doorDevice.DeviceName,
				"store_id":       storeId,
				"operation_time": time.Now().Unix(),
			},
		}
		c.ServeJSON()

	case 1: //订单
		// 根据会员和场地ID查找有效订单
		now := time.Now().Unix()
		order, err := models.GetActiveOrderByVenueIdAndMemberId(venue_id, member.Id, now)
		if err != nil {
			logs.Error("获取场地订单失败: %v, venue_id: %d, member_id: %d", err, venue_id, member.Id)
			c.Data["json"] = map[string]interface{}{"success": false, "message": "获取订单信息失败"}
			c.ServeJSON()
			return
		}
		if order == nil {
			c.Data["json"] = map[string]interface{}{"success": false, "message": "未找到当前时间的有效订单"}
			c.ServeJSON()
			return
		}

		// 计算剩余时间作为delay (单位: 秒)
		delay := int(order.EndTime - now)
		if delay <= 0 {
			c.Data["json"] = map[string]interface{}{"success": false, "message": "订单已结束，无法操作"}
			c.ServeJSON()
			return
		}

		cmd := fmt.Sprintf(`{"deviceId":"%s","command":"1004","params":"{\"Cmd\":\"Order\",\"ID\":%d,\"Lock\":190,\"Type\":1,\"Delay\":%d}"}`, doorDevice.DeviceNo, order.Id, delay)
		success, errorMsg := sendCommand(doorDevice, cmd)
		if !success {
			logs.Error("发送指令失败: %s", errorMsg)
			c.Data["json"] = map[string]interface{}{
				"success": false,
				"message": "操作失败: " + errorMsg,
			}
			c.ServeJSON()
			return
		}

		// 记录开门日志
		logEntry := &models.OperationLog{
			UserId:        member.Id,
			Username:      member.Phone,
			Method:        c.Ctx.Request.Method,
			Path:          c.Ctx.Request.URL.Path,
			Ip:            c.Ctx.Input.IP(),
			OperationType: "device:order",
			Description:   "用户操作开电，门店ID: " + storeIdStr + ", 设备ID: " + strconv.FormatInt(doorDevice.Id, 10),
		}
		err = models.AddOperationLog(logEntry)
		if err != nil {
			logs.Error("记录开门日志失败: %v", err)
		}

		// 返回成功结果
		c.Data["json"] = map[string]interface{}{
			"success": true,
			"message": "操作成功",
			"data": map[string]interface{}{
				"device_name":    doorDevice.DeviceName,
				"store_id":       storeId,
				"operation_time": time.Now().Unix(),
			},
		}
		c.ServeJSON()
	}
}

// 发送开门指令到设备
func sendCommand(device *models.Device, cmd string) (bool, string) {
	// 如果没有配置API端点，返回模拟成功
	// 在实际生产环境中，这里应当根据设备类型和API进行实际通信
	if device.ApiEndpoint == "" {
		logs.Warning("设备未配置API端点，模拟开门成功, deviceId: %d", device.Id)
		return true, ""
	}

	logs.Info("发送指令到设备: %s, cmd: %s", device.DeviceName, cmd)

	client := &http.Client{
		Timeout: 10 * time.Second,
	}

	// 发送请求
	req, err := http.NewRequest("POST", device.ApiEndpoint, bytes.NewBuffer([]byte(cmd)))
	if err != nil {
		return false, "创建HTTP请求失败"
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", device.ApiKey)

	resp, err := client.Do(req)
	if err != nil {
		return false, "与设备通信失败: " + err.Error()
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return false, "读取设备响应失败"
	}

	// 解析响应
	var response map[string]interface{}
	err = json.Unmarshal(body, &response)
	if err != nil {
		return false, "解析设备响应失败"
	}

	// 检查响应状态
	if success, ok := response["success"].(bool); ok && success {
		return true, ""
	} else {
		errMsg := "设备返回错误"
		if msg, ok := response["message"].(string); ok {
			errMsg = msg
		}
		return false, errMsg
	}
}
